<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

/**
 * App\Models\Coupon
 *
 * @property int $coupon_id 优惠券id 主键自增
 * @property string|null $title 优惠券名称
 * @property string|null $code 优惠券券码
 * @property string $send_type  1：会员领取 2：系统自动发放
 * @property int $rule_id coupon_rule表的外键
 * @property int $send_num 发放数
 * @property int $get_num 领取数
 * @property int $use_num 使用数
 * @property int|null $start_time 开始时间的时间戳
 * @property int|null $end_time 结束时间的时间戳
 * @property int $disabled 是否删除 0-否 1-是
 * @property string $status 0：准备中1：待审核； 2：待生效；3：已生效；4：已完成；5：中止  9：已作废
 * @property \Carbon\Carbon|null $created_at
 * @property \Carbon\Carbon|null $updated_at
 * @property int $limit_per_get 每人限制领取的数量 -1代表可以无限领取
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereCode($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereCouponId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereDisabled($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereEndTime($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereGetNum($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereLimitPerGet($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereRuleId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereSendNum($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereSendType($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereStartTime($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereStatus($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereTitle($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereUpdatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Coupon whereUseNum($value)
 * @mixin \Eloquent
 */
class Coupon extends Model
{
    protected $primaryKey = 'coupon_id';
    protected $table = 'coupon';
    protected $guarded = [];

    public static $error;

    public $status = [
        '0' => '可以使用',
        '1' => '已失效(过期)',
    ];
    /**
     * 后台优惠券列表
     */
    public function back_coupon_list()
    {

    }

    /**创建或者编辑优惠券
     * @param $attributes
     * @return bool
     */
    public function save_coupon($attributes)
    {
        $attributes['start_time'] = strtotime($attributes['start_time']);
        $attributes['end_time'] = strtotime($attributes['end_time']);
        if(!isset($attributes['send_num'])){
            //-1代表无数量限制
            $attributes['send_num'] = -1;
        }
        if(!isset($attributes['limit_per_get'])){
            //-1代表无数量限制
            $attributes['limit_per_get'] = -1;
        }
        if(empty($attributes['coupon_id'])){
            $res = self::create($attributes);
        }else{
            $res = self::where('coupon_id',$attributes['coupon_id'])->update($attributes);
        }
        if(!$res){
            return false;
        }

        return true;
    }

    /**优惠券的删除
     * @param $coupon_id
     * @return bool
     */
    public function del_coupon($coupon_id)
    {
        if(empty($coupon_id)){
            return true;
        }
        $attributes['disabled'] = '1';
        if(self::where('coupon_id',$coupon_id)->update(['disabled'=>'1'])){
            return true;
        }
        return false;
    }

    /**系统发放的优惠券列表
     * @return array
     */
    public function api_sys_coupon_list()
    {
        //查询出所有未过期的可以领取的系统发放的优惠券列表
        $time = time();
        $coupon_list = Coupon::query()
            ->select('reduce_type','conditions','actions','coupon.title','start_time','end_time','send_num','get_num','coupon_id')
            ->where('start_time','<=',$time)
            ->where('end_time','>',$time)
            ->where('coupon.disabled','=',0)
            ->where('coupon_rule.disabled','=',0)
            ->join('coupon_rule','coupon_rule.rule_id','=','coupon.rule_id')
            ->get()
            ->toArray();
        $coupon_rule_model = new CouponRule();
        //遍历数组进行解析
        foreach($coupon_list as &$coupon)
        {
            $coupon['explain'] = $coupon_rule_model-> rule_type[$coupon['reduce_type']];
            $this -> format_coupon($coupon);
        }

        return $coupon_list;
    }

    /**
     * 领取优惠券
     */
    public function api_receive_coupon($user_id,$coupon_id)
    {
        $coupon_model = self::find($coupon_id);
        if(empty($coupon_model)){
            self::$error = '无效的优惠券';
            return false;
        }
        //检查该优惠券是否已经过期
        if($coupon_model->end_time<time()){
            self::$error = '该优惠券已经过期';
            return false;
        }

        //优惠券剩余量小于0
        if($coupon_model->send_num - $coupon_model -> get_num <= 0){
            self::$error = '该优惠券已经被领取完了';
            return false;
        }

        $got_coupon_num = CouponUser::query()
            ->where('user_id','=',$user_id)
            ->where('disabled','=',0)
            ->where('coupon_id','=',$coupon_id)
            ->count();

        //个人达到领取该优惠券的限制数量
        if($coupon_model -> limit_per_get > 0 && $coupon_model -> limit_per_get < $got_coupon_num + 1 ){
            self::$error = '该优惠券每人领取只能领取'.$coupon_model -> limit_per_get.'次';
            return false;
        }

        //将优惠券表的优惠券获取数量加1
        $coupon_model -> get_num += 1;
        $coupon_model -> save();

        //在优惠券用户关联表上生成新的记录
        $row = CouponUser::create([
            'user_id'   => $user_id,
            'coupon_id' => $coupon_id,
            'code'      => $this -> generate_code(),
            'get_time'  => time(),
        ]);

        if($row > 0){
            return true;
        }
        self::$error = '优惠券领取失败请稍后再试';
        return false;
    }

    /**用户优惠券列表(包括已失效的和未失效的)
     * @param $user_id
     */
    public function api_user_coupon($user_id)
    {
        $coupon_list = CouponUser::query()
            ->select('coupon_users.id AS coupon_users_id','coupon.title','coupon_users.code','start_time','end_time','conditions','actions','reduce_type')
            ->where('user_id','=',$user_id)
            ->where('coupon.disabled','=',0)
            ->where('coupon_rule.disabled','=',0)
            ->where('coupon_users.disabled','=',0)
            ->join('coupon','coupon.coupon_id','=','coupon_users.coupon_id')
            ->join('coupon_rule','coupon_rule.rule_id','=','coupon.rule_id')
            ->get();
        $coupon_rule_model = new CouponRule();
        $coupon_new_list = [
            'normal_list'  => [],
            'disable_list' => [],
        ];
        foreach($coupon_list as &$coupon)
        {
            $coupon['explain'] = $coupon_rule_model-> rule_type[$coupon['reduce_type']];
            $coupon['status']  = time() > $coupon['end_time'] ? 0 : 1;
            $this -> format_coupon($coupon);
            if($coupon['status'] > 0){
                $coupon_new_list['normal_list'][]  = $coupon;
            }else{
                $coupon_new_list['disable_list'][] = $coupon;
            }
        }

        return $coupon_new_list;
    }

    /**根据订单的总金额来获取可使用的和不可使用的以及优惠力度最大的优惠券
     * @param $user_id
     * @param $total_money
     * @return array
     */
    public function api_order_canuse_coupon($user_id,$total_money)
    {
        $coupon_list = $this -> api_user_coupon($user_id)['normal_list'];
        $new_coupon_list = [
            'can_use'     => [], //可以使用的优惠券列表
            'cannot_use'  => [], //因为不满足最低金额或者其他原因无法使用的券列表
            'default_use' => [], //默认使用优惠力度最大的那个券
        ];

        $can_discount_money = 0;
        $default_use_coupon = [];
        //遍历改用户可用的优惠券列表筛选出满足该优惠券最低金额的列表
        foreach($coupon_list as $coupon){
            //满足最低金额的条件
            if($coupon['min_money'] <= $total_money){
                $new_coupon_list['can_use'][] = $coupon;
                if($coupon['reduce_type'] == 'subtract'){
                    if($coupon['discount_money'] > $can_discount_money){
                        $can_discount_money = $coupon['discount_money'];
                        $new_coupon_list['default_use'] = $coupon;
                    }
                }else if($coupon['reduce_type'] == 'freeship'){
                    #需要确定包邮价格 暂时无法实现
                }else if($coupon['reduce_type'] == 'discount'){
                    if($total_money - $total_money.$coupon['discount_money'] / 10 > $can_discount_money){
                        $can_discount_money = $coupon['discount_money'];
                        $new_coupon_list['default_use'] = $coupon;
                    }
                }
            }else{
                $new_coupon_list['cannot_use'][] = $coupon;
            }
        }

        return $new_coupon_list;
    }

    /**生成唯一的优惠券码
     * @return string
     */
    private function generate_code($code_length=12)
    {
        if(empty($code_length) || $code_length < 0){
            $code_length = 12;
        }
        if($code_length > 23){
            $code_length = 23;
        }
        $code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $rand = $code[rand(0,25)]
            .strtoupper(dechex(date('m')))
            .date('d').substr(time(),-5)
            .substr(microtime(),2,5)
            .sprintf('%04d',rand(0,9999));
        for(
            $a = md5( $rand),
            $s = '0123456789ABCDEFGHIJKLMNOPQRSTUV',
            $d = '',
            $f = 0;
            $f < $code_length;
            $g = ord( $a[ $f ] ),
            $d .= $s[ ( $g ^ ord( $a[ $f + 8 ] ) ) - $g & 0x1F ],
            $f++
        );
        return $d;
    }

    /*格式化数组
     * @param $coupon
     */
    private function format_coupon(&$coupon)
    {
        $conditions = unserialize($coupon['conditions']);
        $actions    = unserialize($coupon['actions']);
        $coupon['min_money'] = $conditions['min_amount'];

        if ($coupon['reduce_type'] == 'subtract') {       //满减
            $coupon['discount_money'] = $actions['order_amount'];
        } elseif ($coupon['reduce_type'] == 'freeship') { //包邮
            $coupon['discount_money'] = $actions['ship_amount'];
        } elseif ($coupon['reduce_type'] == 'discount') { //折扣
            $coupon['discount_money'] = $actions['discount'];
        }

        $coupon['start_time'] = date('Y.m.d',$coupon['start_time']);
        $coupon['end_time']   = date('Y.m.d',$coupon['end_time']);
        unset($coupon['conditions'],$coupon['actions']);
    }

    /**
     * 根据rule_id查出该规则的优惠金额
     */
    public static function get_order_coupon_money($coupon_users_id,$order_item)
    {
        $coupon_user = CouponUser::find($coupon_users_id);
        $rule_model = Coupon::query()
            -> where('coupon_id','=',$coupon_user->coupon_id)
            -> join('coupon_rule','coupon_rule.rule_id','=','coupon.rule_id')
            -> first();
        if($rule_model->reduce_type =='freeship'){
            return '免邮';
        }

        return $order_item['pay_fee'] - $order_item['money_paid'];
    }



}
